package work.shyk.portal.baiduAPI;

import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
 * description: <br>
 * createTime: 2018/11/14 15:55 <br>
 *
 * @author zzh
 */
public class BaiduTjApiClient {

    /**
     * 用户名
     */
    private static final String USER_NAME = "regedit0726";

    /**
     * 密码
     */
    private static final String PASSWORD = "Pcitc123";

    /**
     * token
     */
    private static final String TOKEN = "9a84de531b2f0e4b1c8ea9057a345ff1";

    /**
     * AccountType
     */
    private static final String ACCOUNT_TYPE = "1";

    /**
     * siteId
     */
    private static final String SITE_ID = "12778214";

    /**
     * 编码
     */
    private static final String CHARSET = "utf-8";

    /**
     * 接口基本地址
     */
    private static final String BASE_URL = "https://api.baidu.com/json/tongji/v1/ReportService/";

    /**
     * 获取站点列表接口地址
     */
    private static final String URL_GETSITELIST = "getSiteList";

    /**
     * 获取报告接口地址
     */
    private static final String URL_GETDATA = "getData";

    private static final JSONObject header = new JSONObject();

    static {
        header.put("username", USER_NAME);//用户名
        header.put("password", PASSWORD);//用户密码
        header.put("token", TOKEN);//申请到的token
        header.put("account_type", ACCOUNT_TYPE);
    }

    /**
     * 调用获取站点列表接口
     * @return
     */
    public static String getSiteList() {
        JSONObject params = new JSONObject();
        params.put("header", header);
        byte[] res = new byte[0];
        try {
            res = HttpsUtil.post(BASE_URL + URL_GETSITELIST, params.toString(), CHARSET);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(res);
    }


    /**
     * 调用getData接口获取所有指标数据
     * @param method
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getAllData(GetDataMethod method, String startDate, String endDate) {
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("start_date", startDate);
        paramMap.put("end_date", endDate);
        return getAllData(method, paramMap);
    }

    /**
     * 调用getData接口获取所有指标数据
     * @param method
     * @param paramMap
     * @return
     */
    public static String getAllData(GetDataMethod method, Map<String, Object> paramMap) {
        return getData(method, paramMap, method::getAllMetrics);
    }

    /**
     * 调用getData接口获取默认指标数据
     * @param method
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getDefaultData(GetDataMethod method, String startDate, String endDate) {
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("start_date", startDate);
        paramMap.put("end_date", endDate);
        return getDefaultData(method, paramMap);
    }

    /**
     * 调用getData接口获取默认指标数据
     * @param method
     * @param paramMap
     * @return
     */
    public static String getDefaultData(GetDataMethod method, Map<String, Object> paramMap) {
        return getData(method, paramMap, method::getDefaultMetrics);
    }

    /**
     * 调用getData接口获取指定指标数据
     * @param method
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getDefaultData(GetDataMethod method, String startDate, String endDate, Map<String, Object> paramMap, String metrics) {
        return getData(method, startDate, endDate, paramMap, () -> metrics);
    }

    private static String getData(GetDataMethod method, String startDate, String endDate, Map<String, Object> paramMap, Supplier<String> supplier) {
        paramMap.put("start_date", startDate);
        paramMap.put("end_date", endDate);
        return getData(method, paramMap, supplier);
    }

    public static String getData(GetDataMethod method, Map<String, Object> paramMap, String metrics) {
        return getData(method, paramMap, () -> metrics);
    }

    private static String getData(GetDataMethod method, Map<String, Object> paramMap, Supplier<String> supplier) {
        JSONObject params = new JSONObject();
        params.put("header", header);

        JSONObject body = new JSONObject();
        body.put("siteId",SITE_ID);
        body.put("method", method.getMethod());//需要获取的数据
        body.put("metrics", supplier.get());//指标,数据单位
        body.putAll(paramMap);
        params.put("body", body);
        byte[] res = new byte[0];
        try {
            res = HttpsUtil.post(BASE_URL + URL_GETDATA, params.toString(), CHARSET);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(res);
    }


    /**
     * 把getData接口的method参数所有值定义在枚举类里
     */
    public enum GetDataMethod{

        /**
         *      * 趋势数据
         *      * 指标：
         *      * pv_count(浏览量(PV))
         *      * visitor_count(访客数(UV))
         *      * ip_count(IP数)
         *      * bounce_ratio(跳出率，%)
         *      * avg_visit_time(平均访问时长，秒)
         *      * trans_count(转化次无数)
         *      * contri_pv(百度推荐贡献浏览量)
         */
        OVERVIEW_TIME_TREND(){
            @Override
            public String getMethod() {
                return "overview/getTimeTrendRpt";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,visitor_count,ip_count,bounce_ratio,avg_visit_time,trans_count";
            }
        },
        /**
         * 地域分布
         * 指标：
         * pv_count(浏览量(PV))
         */
        OVERVIEW_DISTRICT(){
            @Override
            public String getMethod() {
                return "overview/getDistrictRpt";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count";
            }
        },
        /**
         * 来源网站、搜索词、入口页面、受访页面
         * 指标：
         * pv_count(浏览量(PV))
         */
        OVERVIEW_COMMON_TRACK(){
            @Override
            public String getMethod() {
                return "overview/getCommonTrackRpt";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count";
            }
        },
        /**
         * 推广方式
         * 指标：
         * show_count(展现量)
         * clk_count(点击量)
         * cost_count(消费，元)
         * ctr(点击率，%)
         * cpm(平均点击价格，元)
         * pv_count(浏览量(PV))
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * in_visit_count(页头访问次数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * arrival_ratio(抵达率)
         *
         * 其他参数：
         * flag:product
         * area
         */
        PRO_PRODUCT(){
            @Override
            public String getMethod() {
                return "pro/product/a";
            }


            @Override
            public String getAllMetrics() {
                return "show_count,clk_count,cost_count,ctr,cpm,pv_count,visit_count,visitor_count," +
                        "new_visitor_count,new_visitor_ratio,in_visit_count,bounce_ratio,avg_visit_time," +
                        "avg_visit_pages,arrival_ratio";
            }
        },
        /**
         * 趋势分析
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * visitorip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         * avg_trans_cost(平均转化成本，元)
         * income (收益，元)
         * profit (利润，元)
         * roi(投资回报率，%)
         *
         * 其他参数：
         * source
         * clientDevice
         * area
         * visitor
         */
        TREND_TIME(){
            @Override
            public String getMethod() {
                return "trend/time/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio," +
                        "avg_trans_cost,income,profit,roi";
            }


            @Override
            public String getDefaultMetrics() {
                return "pv_count,visitor_count,ip_count,bounce_ratio,avg_visit_time,trans_count";
            }
        },
        /**
         * 百度推广趋势
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         * avg_trans_cost(平均转化成本，元)
         * income (收益，元)
         * profit (利润，元)
         * roi(投资回报率，%)
         *
         * 其他参数：
         * clientDevice
         * area
         */
        PRO_HOUR(){
            @Override
            public String getMethod() {
                return "pro/hour/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio," +
                        "avg_trans_cost,income,profit,roi";
            }
        },
        /**
         * 全部来源
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数viewType:type(按来源类型)/site(按来源网站)
         * clientDevice visitor(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * viewType:type(按来源类型)/site(按来源网站)
         * clientDevice
         * visitor
         */
        SOURCE_ALL(){
            @Override
            public String getMethod() {
                return "source/all/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_count,visit_count,visitor_count,clientDevice visitor,new_visitor_count," +
                        "new_visitor_ratio,ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 搜索引擎
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数viewType:type(按来源类型)/site(按来源网站)
         * clientDevice visitor(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * viewType:type(按来源类型)/site(按来源网站)
         * clientDevice
         * visitor
         */
        SOURCE_ENGINE(){
            @Override
            public String getMethod() {
                return "source/engine/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 搜索词
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数viewType:type(按来源类型)/site(按来源网站)
         * clientDevice visitor(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * source
         * clientDevice
         * visitor
         */
        SOURCE_SEARCHWORD(){
            @Override
            public String getMethod() {
                return "source/searchword/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 外部链接
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数viewType:type(按来源类型)/site(按来源网站)
         * clientDevice visitor(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * viewType:domain(按域名)/url(按URL)
         * domainType:1(社会化媒体)/2(导航网站)/4(电子邮箱)
         * clientDevice
         * visitor
         */
        SOURCE_LINK(){
            @Override
            public String getMethod() {
                return "source/link/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 受访页面
         * 指标：
         * pv_count(浏览量(PV))
         * visitor_count(访客数(UV))
         * ip_count(IP数)
         * visit1_count(入口页次数)
         * outward_count(贡献下游浏览量)
         * exit_count(退出页次数)
         * average_stay_time(平均停留时长，秒)
         * exit_ratio(退出率，%)
         *
         * 其他参数：
         * source
         * visitor
         */
        VISIT_TOPPAGE(){
            @Override
            public String getMethod() {
                return "visit/toppage/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,visitor_count,ip_count,visit1_count,outward_count,exit_count," +
                        "average_stay_time,exit_ratio";
            }
        },
        /**
         * 入口页面
         * 指标：
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新无访客比率，%)
         * ip_count(IP数)
         * out_pv_count(贡献浏览量)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         */
        VISIT_LANDINGPAGE(){
            @Override
            public String getMethod() {
                return "visit/landingpage/a";
            }


            @Override
            public String getAllMetrics() {
                return "visit_count,visitor_count,new_visitor_count,new_visitor_ratio,ip_count," +
                        "out_pv_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 受访域名
         * 指标：
         * pv_count(浏览量(PV))
         * pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * average_stay_time(平均停留时长，秒)
         * avg_visit_pages(平均访问页数)
         *
         * 其他参数：
         * source
         * visitor
         */
        VISIT_TOPDOMAIN(){
            @Override
            public String getMethod() {
                return "visit/topdomain/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,average_stay_time,avg_visit_pages";
            }
        },
        /**
         * 地域分布(省)
         * 指标：
         * pv_count(浏览量(PV)) pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平source visitor均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * source
         * visitor
         */
        VISIT_DISTRICT(){
            @Override
            public String getMethod() {
                return "visit/district/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,visit_count,visitor_count,new_visitor_count,new_visitor_ratio,ip_count," +
                        "bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 地域分布(国家)
         * 指标：
         * pv_count(浏览量(PV)) pv_ratio(浏览量占比，%)
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * ip_count(IP数)
         * bounce_ratio(跳出率，%)
         * avg_visit_time(平均访问时长，秒)
         * avg_visit_pages(平source visitor均访问页数)
         * trans_count(转化次数)
         * trans_ratio(转化率，%)
         *
         * 其他参数：
         * source
         * visitor
         */
        VISIT_WORLD(){
            @Override
            public String getMethod() {
                return "visit/world/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,pv_ratio,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "ip_count,bounce_ratio,avg_visit_time,avg_visit_pages,trans_count,trans_ratio";
            }
        },
        /**
         * 事件跟踪
         * 指标：
         * event_count(事件总数)
         * uniq_event_count(唯一访客事件数)
         * event_value(事件价值，元)
         * avg_event_value(平均价值，元)
         *
         * 其他参数：
         * flag:category(类别)/action(操作)/label(标签)
         */
        CUSTOM_EVENT_TRACK(){
            @Override
            public String getMethod() {
                return "custom/event_track/a";
            }


            @Override
            public String getAllMetrics() {
                return "event_count,uniq_event_count,event_value,avg_event_value";
            }
        },
        /**
         * 自定义变量
         * 指标：
         * custom/visit/a pv_count(浏览量(PV))
         * visit_count(访问次数)
         * visitor_count(访客数(UV))
         * new_visitor_count(新访客数)
         * new_visitor_ratio(新访客比率，%)
         * avg_visit_pages(平均访问页数)
         * avg_visit_time(平均访问时长，秒)
         * bounce_ratio(跳出率，%)
         *
         * 其他参数：
         * flag:index1(访客类型1)/index2(访客类型2)/index3(访客类型3)/index4(访客类型4)/index5(访客类型5)
         */
        CUSTOM_VISIT(){
            @Override
            public String getMethod() {
                return "custom/visit/a";
            }


            @Override
            public String getAllMetrics() {
                return "pv_count,visit_count,visitor_count,new_visitor_count,new_visitor_ratio," +
                        "avg_visit_pages,avg_visit_time,bounce_ratio";
            }
        },;

        public abstract String getMethod();

        public abstract String getAllMetrics();

        public String getDefaultMetrics() {
            return getAllMetrics();
        }
    }

    public static void main(String[] args) {
//        String dir = "e:\\json\\";
//        for (GetDataMethod method : GetDataMethod.values()) {
//            if(!method.name().equals("VISIT_TOPDOMAIN") && !method.name().equals("CUSTOM_VISIT")) {
//                continue;
//            }
//            try(BufferedWriter bw = new BufferedWriter(new FileWriter(dir + method.name().toLowerCase() + ".json"))) {
//                bw.write(getData(method, "20181112","20181115"));
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("start_date", "20181129");
        paramMap.put("end_date", "20181129");
        paramMap.put("viewType", "site");

//        System.out.println(getDefaultData(GetDataMethod.SOURCE_ALL, paramMap));
//        System.out.println();
        paramMap.put("visitor", "new");
        System.out.println(getDefaultData(GetDataMethod.SOURCE_ALL, paramMap));
        System.out.println();
        paramMap.put("visitor", "old");
        System.out.println(getDefaultData(GetDataMethod.SOURCE_ALL, paramMap));
        System.out.println();
    }
}
